package org.apereo.cas.configuration.model.support.mfa;

import org.springframework.boot.context.properties.NestedConfigurationProperty;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;

/**
 * This is {@link BaseMultifactorProviderProperties}.
 * 多因素身份验证(MFA)
 * @author Misagh Moayyed
 * @since 5.2.0
 */

@Getter
@Setter
public abstract class BaseMultifactorProviderProperties implements Serializable {

    private static final long serialVersionUID = -2690281104343633871L;

    /**
     * At times, CAS needs to determine the correct provider when step-up authentication is required.
     * Consider for a moment that CAS already has established an SSO session with/without a provider and has
     * reached a level of authentication. Another incoming request attempts to exercise that SSO
     * session with a different and often competing authentication requirement that may differ from the
     * authentication level CAS has already established. Concretely, examples may be:
     * <ul>
     * <li>CAS has achieved an SSO session, but a separate request now requires step-up authentication with DuoSecurity.</li>
     * <li>CAS has achieved an SSO session with an authentication level satisfied by DuoSecurity,
     * but a separate request now requires step-up authentication with YubiKey. </li>
     * </ul>
     * In certain scenarios, CAS will attempt to rank authentication levels and compare them with each other.
     * If CAS already has achieved a level that is higher than what the incoming request requires,
     * no step-up authentication will be performed. If the opposite is true, CAS will route the authentication
     * flow to the required authentication level and upon success, will adjust the SSO session with the
     * new higher authentication level now satisfied.
     * <p>
     * Ranking of authentication methods is done per provider via specific properties for each.
     * Note that the higher the rank value is, the higher on the security scale it remains.
     * A provider that ranks higher with a larger weight value trumps and override others with a lower value.
     * </p>
     * 有时，当需要升级身份验证时，CAS需要确定正确的提供程序。
     *
     * *考虑一下CAS已经建立了一个SSO会话，有/没有提供程序，并且
     *
     * *已达到身份验证级别。另一个传入请求尝试使用该SSO
     *
     * *会话的身份验证要求可能不同于
     *
     * *身份验证级别CA已建立。具体而言，示例可能是：
     *
     * *<ul>
     *
     * *<li>CAS已经实现了一个SSO会话，但是一个单独的请求现在需要使用DuoSecurity进行升级身份验证</li>
     *
     * *<li>CAS已经实现了一个SSO会话，其身份验证级别达到了DuoSecurity的要求，
     *
     * *但另一个请求现在需要使用YubiKey进行升级认证。在</li>
     *
     * *</ul>
     *
     * *在某些情况下，CA将尝试对身份验证级别进行排序，并将其相互比较。
     *
     * *如果CAS已经达到了高于传入请求所需的级别，
     *
     * *不会执行任何升级身份验证。如果相反，CAS将路由身份验证
     *
     * *流到所需的身份验证级别，成功后，将使用
     *
     * *新的更高的身份验证级别现在得到满足。
     *
     * *<p>
     *
     * *身份验证方法的排名是通过每个提供者的特定属性来完成的。
     *
     * *请注意，rank值越高，它保持的安全级别就越高。
     *
     * *权重值越大排名越高的提供者会战胜其他提供者，并以较低的权重值覆盖其他提供者。
     */
    private int rank;

    /**
     * The identifier for the multifactor provider.
     * In most cases, this need not be configured explicitly, unless
     * multiple instances of the same provider type are configured in CAS.
     * *多因素提供程序的标识符。
     * *在大多数情况下，不需要显式配置，除非
     * *在CAS中配置相同提供程序类型的多个实例。
     */
    private String id;

    /**
     * Multifactor bypass options for this provider.
     * Each multifactor provider is equipped with options to allow for MFA bypass. Once the provider is chosen to honor
     * the authentication request, bypass rules are then consulted to calculate whether the provider
     * should ignore the request and skip MFA conditionally.
     * *此供应商的多因素旁路选项。
     * *每个多因素供应商配备选项，允许MFA旁路。一旦提供者被选择去尊重
     * *认证请求后，再咨询绕过规则计算提供者是否
     * *应该忽略请求并有条件地跳过MFA。
     */
    @NestedConfigurationProperty
    private MultifactorAuthenticationProviderBypassProperties bypass = new MultifactorAuthenticationProviderBypassProperties();

    /**
     * The name of the authentication handler used to verify credentials in MFA.
     */
    private String name;

    /**
     * The failure mode policy for this MFA provider.
     */
    private String failureMode = "NOT_SET";
}
